package cn.gaozhong.ymcc.service.impl;

import cn.gaozhong.ymcc.constarts.BaseConstant;
import cn.gaozhong.ymcc.constarts.CommonConstants;
import cn.gaozhong.ymcc.constarts.SmsCodeConstants;
import cn.gaozhong.ymcc.domain.MessageSms;
import cn.gaozhong.ymcc.dto.RedisRegisterDto;
import cn.gaozhong.ymcc.dto.RegisterDto;
import cn.gaozhong.ymcc.exception.CustomException;
import cn.gaozhong.ymcc.service.IMessageSmsService;
import cn.gaozhong.ymcc.service.IVerifyCodeService;
import cn.gaozhong.ymcc.util.AssertUtil;
import cn.gaozhong.ymcc.util.StrUtils;
import cn.gaozhong.ymcc.util.VerifyCodeUtils;
import com.sun.org.apache.bcel.internal.generic.NEW;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.concurrent.TimeUnit;


@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    @Autowired
    private RedisTemplate<Object,Object> redisTemplate;
    @Autowired
    private SmsCodeConstants smsCodeConstants;
    @Autowired
    private IMessageSmsService messageSmsService;
   // @Autowired
//    public UserMapper userMapper;

    /**
     * 图形验证码
     * @param key
     * @return
     */
    @Override
    public String imgCode(String key) {
       if (!StringUtils.hasLength(key)){
            throw  new CustomException("key不能为空");
       }
//        。生成code = 9527
        String code = StrUtils.getComplexRandomString(4);
        redisTemplate.opsForValue().set(key,code,5, TimeUnit.MINUTES);
//        。保存redis，设置过期时间  key是什么==前端请求给我传递的UUID
               //前端传递的UUID
                //图片中的码儿
                //过期时间
                //过期时间的单位
//        。使用2D引擎把code画成图
//        。把图使用Base64编码成字符串
//        。返回Base64编码的字符串
        return VerifyCodeUtils.verifyCode(100,40,code);
    }

    /**
     * 发送短信验证
     * @param mobile
     */
    @Override
    public void sendSmsCode(String mobile) {
//        一：校验
//        1、空校验
//        2、格式校验
        AssertUtil.isNotEmpty(mobile,"电话不能为空");
        AssertUtil.isPhone(mobile,"电话格式不正确");
//        二：验证码
        String key = String.format(CommonConstants.REGISTER_PHONE_PRIFIX, mobile);
        Object o = redisTemplate.opsForValue().get(key);
        Date now = new Date();
        String code="";
        if (o !=null){
//        2、从redis拿到了
            RedisRegisterDto registerDto = (RedisRegisterDto) o;
            boolean b = (now.getTime() - registerDto.getTime()) / 1000 > smsCodeConstants.getInterval();
//        1、校验手机号是否发送过验证码
            AssertUtil.isTrue(b,"验证码还没有过期");
//        2.1没有过重发时间
//        2.2过了重发时间：还没有过期
            code = registerDto.getCode();
        }else {
            //没拿到重新生成
            code = StrUtils.getRandomString(smsCodeConstants.getSize());
        }
        //存储redis
        RedisRegisterDto redisRegisterDto = new RedisRegisterDto(code, now.getTime());
        redisTemplate.opsForValue().set(key,redisRegisterDto,smsCodeConstants.getTimeout(),TimeUnit.SECONDS);
        String message = String.format(smsCodeConstants.getSmsmessage(), code);
        System.out.println(message);
        //存储发送信息到数据库
        saveMessageSms(now, code, message);
    }

    private void saveMessageSms(Date now, String code, String message) {
        MessageSms messageSms = new MessageSms();
        messageSms.setContent(message);
        messageSms.setSendTime(now);
        messageSms.setTitle(smsCodeConstants.getTitle());
        // 获取请求体 request
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        messageSms.setIp(request.getRemoteAddr());
        messageSmsService.insert(messageSms);
    }

}
